package com.slfx.openapi.client.util;

import cn.hutool.core.collection.CollectionUtil;
import com.slfx.open.api.sdk.utils.RsaUtils;
import com.slfx.openapi.client.config.OpenApiConfig;
import com.slfx.openapi.client.config.RetryIntercepter;
import okhttp3.*;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * @author slfx
 * @Description:
 * @date 2021/12/30 11:14
 */
@Component
public class HttpCallUtil {

    private static final Logger LOGGER = LoggerFactory.getLogger(HttpCallUtil.class);

    @Resource
    OpenApiConfig openApiConfig;

    /**
     * get方法调用加签
     *
     * @param reqUrl
     * @param params
     * @param headers
     * @param flag
     * @return
     */
    public  String okHttpGet(String reqUrl, Map<String, Object> params, Map<String, String> headers, boolean flag) {
        OkHttpClient OKHTTP_CLIENT = new OkHttpClient();
        StringBuilder stringBuilder = new StringBuilder();
        //处理参数
        if (params != null && !params.isEmpty()) {
            params.keySet().forEach(res -> {
                if (StringUtils.isNotBlank(stringBuilder) || flag) {
                    stringBuilder.append("&");
                } else {
                    stringBuilder.append("?");
                }
                try {
                    stringBuilder.append(String.format("%s=%s", res, URLEncoder.encode(String.valueOf(params.get(res)), "UTF-8")));
                } catch (UnsupportedEncodingException e) {
                    LOGGER.error("系统异常！", e);
                }

            });
        }
        // 拼接参数
        String requestUrl = reqUrl + stringBuilder;
        Request.Builder reqUrlBuilder = new Request.Builder().url(requestUrl);

        if (CollectionUtil.isNotEmpty(headers)) {
            headers.entrySet().forEach(header -> {
                reqUrlBuilder.addHeader(header.getKey(), header.getValue());
            });
        }
        // 发送请求
        Request request = reqUrlBuilder.get().build();
        Response response = null;
        try {
            LOGGER.info("url:{},headers:{},调用参数:{}", requestUrl, headers, request);
            response = OKHTTP_CLIENT.newCall(request).execute();
            String result = response.body().string();
            LOGGER.info("url:{},返回结果:{}", requestUrl, result);
            return result;
        } catch (Exception e) {
            throw new RuntimeException("HTTP GET同步请求失败 URL:" + reqUrl, e);
        } finally {
            response.close();
        }
    }

    /**
     * post方法调用加签
     *
     * @param reqUrl
     * @param params
     * @param contentType
     * @param headers
     * @return
     */
    public  String okHttpPost(String reqUrl, String params, String contentType, Map<String, String> headers) {
        OkHttpClient client = new OkHttpClient().newBuilder()
                .connectTimeout(80, TimeUnit.SECONDS)
                .addInterceptor(new RetryIntercepter(3))
                .readTimeout(80, TimeUnit.SECONDS).writeTimeout(80, TimeUnit.SECONDS)
                .build();
        MediaType mediaType = MediaType.parse(contentType);
        RequestBody body = RequestBody.create(mediaType, params);
        Request.Builder reqUrlBuilder = new Request.Builder().url(reqUrl);
        if (CollectionUtil.isNotEmpty(headers)) {
            headers.entrySet().forEach(header -> {
                reqUrlBuilder.addHeader(header.getKey(), header.getValue());
            });
        }
        Request request = reqUrlBuilder.post(body).build();
        try {
            LOGGER.info("url:{},headers:{},调用参数:{}", reqUrl, headers, body);
            Response response = client.newCall(request).execute();
            String result = response.body().string();
            LOGGER.info("url:{},返回结果:{}", reqUrl, result);
            return result;
        } catch (Exception e) {
            throw new RuntimeException("HTTP POST同步请求失败 URL:" + reqUrl, e);
        }
    }


    /**
     * post发送消息
     *
     * @param url
     * @param postParams
     * @return
     * @throws Exception
     */
    public  String sendOpenApiPost(String url, String postParams) throws Exception {
        String timeStamp = String.valueOf(System.currentTimeMillis());
        //加签
        String sign = RsaUtils.sign(openApiConfig.getAppId(), url, postParams, timeStamp, openApiConfig.getPrivateKey());
        Map<String, String> headerMap = new HashMap<>();
        headerMap.put("appId",openApiConfig.getAppId());
        headerMap.put("timeStamp", timeStamp);
        headerMap.put("sign", sign);
        return okHttpPost(url, postParams, "application/json", headerMap);
    }


    /**
     * get发送消息
     *
     * @param url 调用的url
     * @param params 调用的参数
     * @return
     * @throws Exception
     */
    public  String sendOpenApiGet(String url, Map<String, Object> params) throws Exception {
        String timeStamp = String.valueOf(System.currentTimeMillis());
        //加签url处理
        String sign = RsaUtils.sign(openApiConfig.getAppId(), url, null, timeStamp, openApiConfig.getPrivateKey());
        Map<String, String> headerMap = new HashMap<>();
        headerMap.put("appId", openApiConfig.getAppId());
        headerMap.put("timeStamp", timeStamp);
        headerMap.put("sign", sign);
        return okHttpGet(url, params, headerMap, false);
    }
}

